package com.landinfo.web.rest;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.codahale.metrics.annotation.Timed;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.landinfo.domain.DynamicTemplate;
import com.landinfo.service.DynamicTemplateService;
import com.landinfo.service.GpsLocationService;
import com.landinfo.service.impl.DynamicTemplateServiceImpl;
import com.landinfo.web.rest.vm.DynamicTemplateHistoryVM;
import com.landinfo.web.rest.vm.DynamicTemplateTotalVM;
import io.swagger.annotations.ApiParam;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.domain.Pageable;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Created by ziqilv on 2017/7/5.
 * 动态模板（动态表单、动态表）
 */
@RestController
@RequestMapping("/api")
public class DynamicTemplateResource {

    private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    final SseEmitter collectionDataSseEmitter = new SseEmitter();
    private final CopyOnWriteArrayList<SseEmitter> emitters = new CopyOnWriteArrayList<>();

    //    @Autowired
    private DynamicTemplateService dynamicTemplateService;
    private final GpsLocationService gpsLocationService;

    public DynamicTemplateResource(DynamicTemplateService dynamicTemplateService,GpsLocationService gpsLocationService) {
        this.dynamicTemplateService = dynamicTemplateService;
        this.gpsLocationService = gpsLocationService;

        this.generateXmlFromDatabase();
    }


    /**
     * GET  获取最近一分钟的监测数据
     *
     * @return the ResponseEntity with status 200 (OK) and the list of dataTypes in body
     */
    @GetMapping("/getOneMinutesMonitorData")
    @Timed
    public String getOneMinutesMonitorData() {
        return JSON.toJSONStringWithDateFormat(this.dynamicTemplateService.getOneMinutesMonitorData(false), "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
    }

    /**
     * 获取今天监测数据
     *
     * @return
     */
    @GetMapping("/getTodayMonitorData")
    @Timed
    public String getTodayMonitorData() {
        return JSON.toJSONStringWithDateFormat(this.dynamicTemplateService.getOneMinutesMonitorData(true), "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
    }


    /**
     * 创建模板（表单）
     *
     * @return
     */
    @PostMapping("/dynamic-template")
    @Timed
    public String createTemplate(@RequestBody DynamicTemplate dynamicTemplate) {
        return this.dynamicTemplateService.createTemplate(dynamicTemplate);
    }

    /**
     * 根据类型查看动态模板
     *
     * @param type
     * @return
     */
    @GetMapping("/dynamic-template/allByType/{type}")
    @Timed
    public String queryDynamicTemplate(@PathVariable String type) {
        String res = this.dynamicTemplateService.queryDynamicTemplate(type);
        return res;
    }

    /**
     * 查询动态模板表（DynamicTemplate）中数据
     *
     * @param type
     * @return
     */
    @GetMapping("/dynamic-template/all2/{type}")
    @Timed
    public String queryDynamicTemplate2(@PathVariable String type) {
        return this.dynamicTemplateService.queryDynamicTemplate2(type);
    }

    /**
     * 同步动态模板表（DynamicTemplate）中数据
     *
     * @return
     */
    @GetMapping("/dynamic-template/synchronize/{userName}/{deviceId}")
    @Timed
    public String synchronizeDynamicTemplate(@PathVariable String userName, @PathVariable String deviceId) {
        if (deviceId != null) {
            userName += deviceId;
        }
        String result = this.dynamicTemplateService.queryDynamicTemplate2(null, userName);
        if (result != null) {
            this.dynamicTemplateService.updateDynamicTemplateUser(userName);
        }
        return result;
    }

    /**
     * 删除指定用户已更新状态
     *
     * @return
     */
    @GetMapping("/dynamic-template/synchronize/update/{userName}/{deviceId}")
    @Timed
    public Boolean synchronizeUpdateDynamicTemplate(@PathVariable String userName, @PathVariable String deviceId) {
        if (deviceId != null) {
            userName += deviceId;
        }
        Boolean isOk = this.dynamicTemplateService.deleteUpdatedDynamicTemplate(userName);
        return isOk;
    }

    @GetMapping("/dynamic-template/all/{userName}/{entityName}")
    @Timed
    public String getAllRecords(@PathVariable String userName, @PathVariable String entityName, @ApiParam Pageable pageable) {
        return this.dynamicTemplateService.getAllRecords(userName, entityName, pageable);
    }

    /**
     * 根据监测样线的id获取某模板对应的所有数据
     * @param userName
     * @param entityName
     * @param simpleLineId
     * @return
     */
    @GetMapping("/dynamic-template/simpleLine/all/{userName}/{entityName}/{simpleLineId}")
    @Timed
    public String getAllSimpleLineRecords(@PathVariable String userName, @PathVariable String entityName, @PathVariable Long simpleLineId) {
        return this.dynamicTemplateService.getAllSimpleLineRecords(userName, entityName, simpleLineId);
    }

    @GetMapping("/dynamic-table/{entityName}")
    @Timed
    public String getDynamicTable(@PathVariable String entityName) {

        return this.dynamicTemplateService.getDynamicTable(entityName);
    }
    @PostMapping("/dynamic-table/total/{para}")
    @Timed
    public String totalDynamicTable(@PathVariable String para, @RequestParam String geom) {
        try {
            JSONObject jsonObject = JSON.parseObject(para);
            String tableName = jsonObject.getString("tableName");
            String where = jsonObject.getString("where");
            // String geom = jsonObject.getString("geometry");
            String groupField = jsonObject.getString("groupField");
            String totalType = jsonObject.getString("totalType");
            String totalField = jsonObject.getString("totalField");
            List list = this.dynamicTemplateService.totalDynamicTable(tableName, where, geom, groupField, totalType, totalField);
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            return gson.toJson(list);
        } catch (Exception ex) {
            return String.format("{error:%s}", ex.getLocalizedMessage());
        }
    }
    /**
     * 保存动态模板数据（保存动态表单数据）
     *
     * @return
     */
    @PostMapping("/dynamic-template/save")
    @Timed
    public String saveDynamicTable(@RequestBody DynamicTemplate dynamicTemplate) {
        //将gps数据清空
        String result = this.dynamicTemplateService.saveDynamicTable(dynamicTemplate);
        if ("monitor".equals(dynamicTemplate.getType())) {
            //this.collectionPush();
        }
        return result;
    }

    /**
     * 保存动态模板数据（保存动态表单数据）
     *
     * @return
     */
    @PostMapping("/dynamic-table/save")
    @Timed
    public String saveDynamicTable2(@RequestBody DynamicTemplate dynamicTemplate) {
        return this.saveDynamicTable(dynamicTemplate);
    }

    /**
     * 保存动态模板数据（保存动态表单数据）
     *
     * @return
     */
    @PostMapping("/dynamic-table/saves")
    @Timed
    public List<String> saveDynamicTables(@RequestBody List<DynamicTemplate> dynamicTables) {
        if (dynamicTables == null || dynamicTables.size() <= 0) {
            return null;
        }
        //将gps数据清空
        List<String> result = new ArrayList<>();
        for (int i = 0; i < dynamicTables.size(); i++) {
            result.add(this.dynamicTemplateService.saveDynamicTable(dynamicTables.get(i)));
        }
        return result;
    }

    /**
     * 根据模板类型和parentId获取动态表数据
     *
     * @param type
     * @param parentId
     * @param loadChildTableData 是否加载子表数据
     * @return
     */
    @GetMapping("/dynamic-table/{type}/{parentId}/{loadChildTableData}/{loadDomain}")
    @Timed
    public String getMultChildTableDynamicTable(@PathVariable String type, @PathVariable String parentId, @PathVariable Boolean loadChildTableData, @PathVariable Boolean loadDomain) {
        if (type == null || parentId == null) {
            return null;
        }
        String result = this.dynamicTemplateService.getMultChildTableDynamicTable(type, parentId, loadChildTableData, loadDomain);
        return result;
    }

    @GetMapping("/dynamic-template/{entityName}/{id}")
    @Timed
    public String getTemplate(@PathVariable String entityName, @PathVariable String id) {
        return dynamicTemplateService.getTemplate(entityName, id);
    }

    @PostMapping("/dynamic-template/unique/{entityName}")
    @Timed
    public String getFieldUniqueValue(@PathVariable String entityName, @RequestParam String fieldNames) {
        return dynamicTemplateService.getFieldUniqueValue(entityName, fieldNames);
    }

    @GetMapping("/dynamic-template/find/{dynamicTableName}/{gpsLocationParentId}")
    @Timed
    public String findByDynamicTableNameAndGpsLocationParentId(@PathVariable String dynamicTableName, @PathVariable String gpsLocationParentId) {
        Object dynamicTable = this.dynamicTemplateService.getDynamicTemplateByName(dynamicTableName);
        HashMap<String, Object> resultHashMap = new HashMap<>();
        if (dynamicTable != null) {
            HashMap hashMap = (HashMap) dynamicTable;
            String jsonContent = hashMap.get("jsonContent").toString();
            JSONObject jsonObject = JSON.parseObject(jsonContent);
            Object[] tempFields = jsonObject.keySet().toArray();
            for (int i = 0; i < tempFields.length; i++) {
                resultHashMap.put(tempFields[i].toString(), jsonObject.get(tempFields[i]));
            }
            Object fieldColumnObject = jsonObject.get("fieldColumns");
            if (fieldColumnObject != null) {
                JSONArray fieldColumns = (JSONArray) fieldColumnObject;
                String fieldName = null;
                for (int i = 0; i < fieldColumns.size(); i++) {
                    JSONObject jsonObjectFieldColumn = (JSONObject) fieldColumns.get(i);
                    String frontType = jsonObjectFieldColumn.get("frontType") + "";
                    if ("recordGpsLocation".toUpperCase().equals(frontType.toUpperCase())) {
                        fieldName = jsonObjectFieldColumn.get("fieldNameDatabase") + "";
                        break;
                    }
                }
                if (fieldName != null) {
                    String result = this.dynamicTemplateService.getDynamicTable(dynamicTableName, fieldName + " = '" + gpsLocationParentId + "'");
                    JSONArray jsonArray = JSON.parseArray(result);
                    if (jsonArray != null && jsonArray.size() > 0) {
                        resultHashMap.put("rows", jsonArray.get(0));
                    } else {
                        resultHashMap.put("rows", "");
                    }
                    return JSON.toJSONString(resultHashMap);
                }
            }
        }
        return null;
    }

    @GetMapping("/dynamic-template/getDomains/{dynamicTableName}")
    @Timed
    public String getDomainsByDynamicTableName(@PathVariable String dynamicTableName) {
        Object dynamicTable = this.dynamicTemplateService.getDynamicTemplateByName(dynamicTableName);
        if (dynamicTable != null) {
            HashMap hashMap = (HashMap) dynamicTable;
            String jsonContent = hashMap.get("jsonContent").toString();
            JSONObject jsonObject = JSON.parseObject(jsonContent);
            Object fieldColumnsDomain = jsonObject.get("fieldColumnsDomain");
            if (fieldColumnsDomain != null) {
                return JSON.toJSONString(fieldColumnsDomain);
            }
        }
        return null;
    }

    /**
     * 历史记录
     *
     * @param dynamicTemplateHistoryVM
     * @return
     */
    @PostMapping("/dynamic-template/history")
    @Timed
    public String getHistoryTemplate(@RequestBody DynamicTemplateHistoryVM dynamicTemplateHistoryVM) {
        if (dynamicTemplateHistoryVM == null) {
            return "error:输入参数为空";
        }
        if (dynamicTemplateHistoryVM.getTempName() == null) {
            return "error:输入模板名为空";
        }
        String result = null;
        HashMap<String, Object> dynamicTables = dynamicTemplateService.getHistoryTemplate(dynamicTemplateHistoryVM);
        if (dynamicTables != null) {
            Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
            result = gson.toJson(dynamicTables);
//            result = JSON.toJSONStringWithDateFormat(dynamicTables, "yyyy-MM-dd HH:mm:ss", SerializerFeature.DisableCircularReferenceDetect);
        }
        return result;
    }

    /**
     * 导出历史记录到Excel
     *
     * @param dynamicTemplateHistoryVM
     * @return
     */
    @PostMapping("/dynamic-template/history/excel")
    @Timed
    public String exportHistoryTemplate2Excel(@RequestBody DynamicTemplateHistoryVM dynamicTemplateHistoryVM) {
        return dynamicTemplateService.exportHistoryTemplate2Excel(dynamicTemplateHistoryVM);
    }


    /**
     * 统计分析
     * @param
     * @return
     * @RequestBody DynamicTemplateTotalVM dynamicTemplateTotalVM
     */
    @PostMapping("/dynamic-template/total")
    @Timed
    public String getTotalTemplate(@RequestBody DynamicTemplateTotalVM dynamicTemplateTotalVM) {
        return this.dynamicTemplateService.getTotalTemplate(dynamicTemplateTotalVM);
    }

    /**
     * 统计分析(统计所有表中的某字段)
     * @param
     * @return
     * @RequestBody List<DynamicTemplateTotalVM> dynamicTemplateTotalVMs
     */
    @PostMapping("/dynamic-template/total/allTable")
    @Timed
    public String getTotalAllTemplate(@RequestBody List<DynamicTemplateTotalVM> dynamicTemplateTotalVMs) {
        return this.dynamicTemplateService.getTotalAllTemplate(dynamicTemplateTotalVMs);
    }

    private Boolean generateXmlFromDatabase() {
        return this.dynamicTemplateService.generateXmlFromDatabase();
    }

    @GetMapping("/dynamic-template/del/{entityName}/{id}")
    @Timed
    public String delete(@PathVariable String entityName, @PathVariable String id) {
        String parentId = dynamicTemplateService.getGpsParentIdByTemplateAndId(entityName, id);
        Boolean isOk = dynamicTemplateService.deleteById(entityName, id);
        if(isOk && parentId != null){
            gpsLocationService.deleteByParentId(parentId);
        }
        return isOk.toString();
    }

    @GetMapping("/dynamic-template/recordGpsLocation/{entityName}/{id}")
    @Timed
    public String getGpsParentIdByTemplateAndId(@PathVariable String entityName, @PathVariable String id) {
        String parentId = dynamicTemplateService.getGpsParentIdByTemplateAndId(entityName, id);
        return parentId;
    }

    @GetMapping("/dynamic-template/translate2en/{cn}")
    @Timed
    public String translate(@PathVariable String cn) {
        return DynamicTemplateServiceImpl.getPingYin(cn);
    }


    /**
     * 根据模板类型指定parentId删除动态表数据（针对非级联关联）
     *
     * @param templateType
     * @param parentId
     * @return
     */
    @GetMapping("/dynamic-table/deleteByParentId/{templateType}/{parentId}")
    @Timed
    public Boolean deleteByParentId(@PathVariable String templateType, @PathVariable String parentId) {

        Boolean isOk = this.dynamicTemplateService.deleteByParentId(templateType, parentId);
        return isOk;
    }

//
//    SELECT gid, "类型", "名称", ST_AsText(geom) FROM public.namepoint;
//
//    INSERT INTO public.test3(gid, geom) VALUES('1001', ST_GeomFromText('POINT(11457592.6011 2777071.6995)', 3857));
//
//    CREATE TABLE public.test3
//            (
//                    gid integer NOT NULL ,
//  "类型" character varying(50),
//  "名称" character varying(50),
//    geom geometry(Point,3857),
//    CONSTRAINT test3_pkey PRIMARY KEY (gid)
//)


}
